﻿package org.flixel
{
    import flash.display.*;
    import flash.geom.*;
    import org.flixel.system.*;

    public class FlxSprite extends FlxObject
    {
        protected var ImgDefault:Class;
        public var origin:FlxPoint;
        public var offset:FlxPoint;
        public var scale:FlxPoint;
        public var blend:String;
        public var antialiasing:Boolean;
        public var finished:Boolean;
        public var frameWidth:uint;
        public var frameHeight:uint;
        public var frames:uint;
        public var framePixels:BitmapData;
        public var dirty:Boolean;
        protected var _animations:Array;
        protected var _flipped:uint;
        protected var _curAnim:FlxAnim;
        protected var _curFrame:uint;
        protected var _curIndex:uint;
        protected var _frameTimer:Number;
        protected var _callback:Function;
        protected var _facing:uint;
        protected var _alpha:Number;
        protected var _color:uint;
        protected var _bakedRotation:Number;
        protected var _pixels:BitmapData;
        protected var _flashPoint:Point;
        protected var _flashRect:Rectangle;
        protected var _flashRect2:Rectangle;
        protected var _flashPointZero:Point;
        protected var _colorTransform:ColorTransform;
        protected var _matrix:Matrix;

        public function FlxSprite(param1:Number = 0, param2:Number = 0, param3:Class = null)
        {
            this.ImgDefault = FlxSprite_ImgDefault;
            super(param1, param2);
            health = 1;
            this._flashPoint = new Point();
            this._flashRect = new Rectangle();
            this._flashRect2 = new Rectangle();
            this._flashPointZero = new Point();
            this.offset = new FlxPoint();
            this.origin = new FlxPoint();
            this.scale = new FlxPoint(1, 1);
            this._alpha = 1;
            this._color = 16777215;
            this.blend = null;
            this.antialiasing = false;
            cameras = null;
            this.finished = false;
            this._facing = RIGHT;
            this._animations = new Array();
            this._flipped = 0;
            this._curAnim = null;
            this._curFrame = 0;
            this._curIndex = 0;
            this._frameTimer = 0;
            this._matrix = new Matrix();
            this._callback = null;
            if (param3 == null)
            {
                param3 = this.ImgDefault;
            }
            this.loadGraphic(param3);
            return;
        }// end function

        override public function destroy() : void
        {
            var _loc_1:FlxAnim = null;
            var _loc_2:uint = 0;
            var _loc_3:uint = 0;
            if (this._animations != null)
            {
                _loc_2 = 0;
                _loc_3 = this._animations.length;
                while (_loc_2 < _loc_3)
                {
                    
                    _loc_1 = this._animations[_loc_2++];
                    if (_loc_1 != null)
                    {
                        _loc_1.destroy();
                    }
                }
                this._animations = null;
            }
            this._flashPoint = null;
            this._flashRect = null;
            this._flashRect2 = null;
            this._flashPointZero = null;
            this.offset = null;
            this.origin = null;
            this.scale = null;
            this._curAnim = null;
            this._matrix = null;
            this._callback = null;
            this.framePixels = null;
            return;
        }// end function

        public function loadGraphic(param1:Class, param2:Boolean = false, param3:Boolean = false, param4:uint = 0, param5:uint = 0, param6:Boolean = false) : FlxSprite
        {
            this._bakedRotation = 0;
            this._pixels = FlxG.addBitmap(param1, param3, param6);
            if (param3)
            {
                this._flipped = this._pixels.width >> 1;
            }
            else
            {
                this._flipped = 0;
            }
            if (param4 == 0)
            {
                if (param2)
                {
                    param4 = this._pixels.height;
                }
                else if (this._flipped > 0)
                {
                    param4 = this._pixels.width * 0.5;
                }
                else
                {
                    param4 = this._pixels.width;
                }
            }
            var _loc_7:* = param4;
            this.frameWidth = param4;
            width = _loc_7;
            if (param5 == 0)
            {
                if (param2)
                {
                    param5 = width;
                }
                else
                {
                    param5 = this._pixels.height;
                }
            }
            var _loc_7:* = param5;
            this.frameHeight = param5;
            height = _loc_7;
            this.resetHelpers();
            return this;
        }// end function

        public function loadRotatedGraphic(param1:Class, param2:uint = 16, param3:int = -1, param4:Boolean = false, param5:Boolean = false) : FlxSprite
        {
            var _loc_12:BitmapData = null;
            var _loc_13:uint = 0;
            var _loc_14:uint = 0;
            var _loc_15:uint = 0;
            var _loc_16:uint = 0;
            var _loc_17:uint = 0;
            var _loc_18:Number = NaN;
            var _loc_19:uint = 0;
            var _loc_20:uint = 0;
            var _loc_21:uint = 0;
            var _loc_22:uint = 0;
            var _loc_6:* = Math.sqrt(param2);
            var _loc_7:* = FlxG.addBitmap(param1);
            if (param3 >= 0)
            {
                _loc_12 = _loc_7;
                _loc_7 = new BitmapData(_loc_12.height, _loc_12.height);
                _loc_13 = param3 * _loc_7.width;
                _loc_14 = 0;
                _loc_15 = _loc_12.width;
                if (_loc_13 >= _loc_15)
                {
                    _loc_14 = uint(_loc_13 / _loc_15) * _loc_7.height;
                    _loc_13 = _loc_13 % _loc_15;
                }
                this._flashRect.x = _loc_13;
                this._flashRect.y = _loc_14;
                this._flashRect.width = _loc_7.width;
                this._flashRect.height = _loc_7.height;
                _loc_7.copyPixels(_loc_12, this._flashRect, this._flashPointZero);
            }
            var _loc_8:* = _loc_7.width;
            if (_loc_7.height > _loc_8)
            {
                _loc_8 = _loc_7.height;
            }
            if (param5)
            {
                _loc_8 = _loc_8 * 1.5;
            }
            var _loc_9:* = FlxU.ceil(param2 / _loc_6);
            width = _loc_8 * _loc_9;
            height = _loc_8 * _loc_6;
            var _loc_10:* = String(param1) + ":" + param3 + ":" + width + "x" + height;
            var _loc_11:* = FlxG.checkBitmapCache(_loc_10);
            this._pixels = FlxG.createBitmap(width, height, 0, true, _loc_10);
            var _loc_23:* = this._pixels.width;
            this.frameWidth = this._pixels.width;
            width = _loc_23;
            var _loc_23:* = this._pixels.height;
            this.frameHeight = this._pixels.height;
            height = _loc_23;
            this._bakedRotation = 360 / param2;
            if (!_loc_11)
            {
                _loc_16 = 0;
                _loc_18 = 0;
                _loc_19 = _loc_7.width * 0.5;
                _loc_20 = _loc_7.height * 0.5;
                _loc_21 = _loc_8 * 0.5;
                _loc_22 = _loc_8 * 0.5;
                while (_loc_16 < _loc_6)
                {
                    
                    _loc_17 = 0;
                    while (_loc_17 < _loc_9)
                    {
                        
                        this._matrix.identity();
                        this._matrix.translate(-_loc_19, -_loc_20);
                        this._matrix.rotate(_loc_18 * 0.0174533);
                        this._matrix.translate(_loc_8 * _loc_17 + _loc_21, _loc_22);
                        _loc_18 = _loc_18 + this._bakedRotation;
                        this._pixels.draw(_loc_7, this._matrix, null, null, null, param4);
                        _loc_17 = _loc_17 + 1;
                    }
                    _loc_22 = _loc_22 + _loc_8;
                    _loc_16 = _loc_16 + 1;
                }
            }
            var _loc_23:* = _loc_8;
            height = _loc_8;
            var _loc_23:* = _loc_23;
            width = _loc_23;
            var _loc_23:* = _loc_23;
            this.frameHeight = _loc_23;
            this.frameWidth = _loc_23;
            this.resetHelpers();
            if (param5)
            {
                width = _loc_7.width;
                height = _loc_7.height;
                this.centerOffsets();
            }
            return this;
        }// end function

        public function makeGraphic(param1:uint, param2:uint, param3:uint = 4.29497e+009, param4:Boolean = false, param5:String = null) : FlxSprite
        {
            this._bakedRotation = 0;
            this._pixels = FlxG.createBitmap(param1, param2, param3, param4, param5);
            var _loc_6:* = this._pixels.width;
            this.frameWidth = this._pixels.width;
            width = _loc_6;
            var _loc_6:* = this._pixels.height;
            this.frameHeight = this._pixels.height;
            height = _loc_6;
            this.resetHelpers();
            return this;
        }// end function

        protected function resetHelpers() : void
        {
            this._flashRect.x = 0;
            this._flashRect.y = 0;
            this._flashRect.width = this.frameWidth;
            this._flashRect.height = this.frameHeight;
            this._flashRect2.x = 0;
            this._flashRect2.y = 0;
            this._flashRect2.width = this._pixels.width;
            this._flashRect2.height = this._pixels.height;
            if (this.framePixels == null || this.framePixels.width != width || this.framePixels.height != height)
            {
                this.framePixels = new BitmapData(width, height);
            }
            this.origin.make(this.frameWidth * 0.5, this.frameHeight * 0.5);
            this.framePixels.copyPixels(this._pixels, this._flashRect, this._flashPointZero);
            this.frames = this._flashRect2.width / this._flashRect.width * (this._flashRect2.height / this._flashRect.height);
            if (this._colorTransform != null)
            {
                this.framePixels.colorTransform(this._flashRect, this._colorTransform);
            }
            this._curIndex = 0;
            return;
        }// end function

        override public function postUpdate() : void
        {
            super.postUpdate();
            this.updateAnimation();
            return;
        }// end function

        override public function draw() : void
        {
            var _loc_1:FlxCamera = null;
            if (_flickerTimer != 0)
            {
                _flicker = !_flicker;
                if (_flicker)
                {
                    return;
                }
            }
            if (this.dirty)
            {
                this.calcFrame();
            }
            if (cameras == null)
            {
                cameras = FlxG.cameras;
            }
            var _loc_2:uint = 0;
            var _loc_3:* = cameras.length;
            while (_loc_2 < _loc_3)
            {
                
                _loc_1 = cameras[_loc_2++];
                if (this.onScreen(_loc_1))
                {
                    _point.x = x - int(_loc_1.scroll.x * scrollFactor.x) - this.offset.x;
                    _point.y = y - int(_loc_1.scroll.y * scrollFactor.y) - this.offset.y;
                    _point.x = _point.x + (_point.x > 0 ? (1e-007) : (-1e-007));
                    _point.y = _point.y + (_point.y > 0 ? (1e-007) : (-1e-007));
                    if ((angle == 0 || this._bakedRotation > 0) && this.scale.x == 1 && this.scale.y == 1 && this.blend == null)
                    {
                        this._flashPoint.x = _point.x;
                        this._flashPoint.y = _point.y;
                        _loc_1.buffer.copyPixels(this.framePixels, this._flashRect, this._flashPoint, null, null, true);
                    }
                    else
                    {
                        this._matrix.identity();
                        this._matrix.translate(-this.origin.x, -this.origin.y);
                        this._matrix.scale(this.scale.x, this.scale.y);
                        if (angle != 0 && this._bakedRotation <= 0)
                        {
                            this._matrix.rotate(angle * 0.0174533);
                        }
                        this._matrix.translate(_point.x + this.origin.x, _point.y + this.origin.y);
                        _loc_1.buffer.draw(this.framePixels, this._matrix, null, this.blend, null, this.antialiasing);
                    }
                    var _loc_5:* = _VISIBLECOUNT + 1;
                    _VISIBLECOUNT = _loc_5;
                    if (FlxG.visualDebug && !ignoreDrawDebug)
                    {
                        drawDebug(_loc_1);
                    }
                }
            }
            return;
        }// end function

        public function stamp(param1:FlxSprite, param2:int = 0, param3:int = 0) : void
        {
            param1.drawFrame();
            var _loc_4:* = param1.framePixels;
            if ((param1.angle == 0 || param1._bakedRotation > 0) && param1.scale.x == 1 && param1.scale.y == 1 && param1.blend == null)
            {
                this._flashPoint.x = param2;
                this._flashPoint.y = param3;
                this._flashRect2.width = _loc_4.width;
                this._flashRect2.height = _loc_4.height;
                this._pixels.copyPixels(_loc_4, this._flashRect2, this._flashPoint, null, null, true);
                this._flashRect2.width = this._pixels.width;
                this._flashRect2.height = this._pixels.height;
                this.calcFrame();
                return;
            }
            this._matrix.identity();
            this._matrix.translate(-param1.origin.x, -param1.origin.y);
            this._matrix.scale(param1.scale.x, param1.scale.y);
            if (param1.angle != 0)
            {
                this._matrix.rotate(param1.angle * 0.0174533);
            }
            this._matrix.translate(param2 + param1.origin.x, param3 + param1.origin.y);
            this._pixels.draw(_loc_4, this._matrix, null, param1.blend, null, param1.antialiasing);
            this.calcFrame();
            return;
        }// end function

        public function drawLine(param1:Number, param2:Number, param3:Number, param4:Number, param5:uint, param6:uint = 1) : void
        {
            var _loc_7:* = FlxG.flashGfx;
            FlxG.flashGfx.clear();
            _loc_7.moveTo(param1, param2);
            var _loc_8:* = Number(param5 >> 24 & 255) / 255;
            if (Number(param5 >> 24 & 255) / 255 <= 0)
            {
                _loc_8 = 1;
            }
            _loc_7.lineStyle(param6, param5, _loc_8);
            _loc_7.lineTo(param3, param4);
            this._pixels.draw(FlxG.flashGfxSprite);
            this.dirty = true;
            return;
        }// end function

        public function fill(param1:uint) : void
        {
            this._pixels.fillRect(this._flashRect2, param1);
            if (this._pixels != this.framePixels)
            {
                this.dirty = true;
            }
            return;
        }// end function

        protected function updateAnimation() : void
        {
            var _loc_1:uint = 0;
            var _loc_2:int = 0;
            if (this._bakedRotation > 0)
            {
                _loc_1 = this._curIndex;
                _loc_2 = angle % 360;
                if (_loc_2 < 0)
                {
                    _loc_2 = _loc_2 + 360;
                }
                this._curIndex = _loc_2 / this._bakedRotation + 0.5;
                if (_loc_1 != this._curIndex)
                {
                    this.dirty = true;
                }
            }
            else if (this._curAnim != null && this._curAnim.delay > 0 && (this._curAnim.looped || !this.finished))
            {
                this._frameTimer = this._frameTimer + FlxG.elapsed;
                while (this._frameTimer > this._curAnim.delay)
                {
                    
                    this._frameTimer = this._frameTimer - this._curAnim.delay;
                    if (this._curFrame == (this._curAnim.frames.length - 1))
                    {
                        if (this._curAnim.looped)
                        {
                            this._curFrame = 0;
                        }
                        this.finished = true;
                    }
                    else
                    {
                        var _loc_3:String = this;
                        var _loc_4:* = this._curFrame + 1;
                        _loc_3._curFrame = _loc_4;
                    }
                    this._curIndex = this._curAnim.frames[this._curFrame];
                    this.dirty = true;
                }
            }
            if (this.dirty)
            {
                this.calcFrame();
            }
            return;
        }// end function

        public function drawFrame(param1:Boolean = false) : void
        {
            if (param1 || this.dirty)
            {
                this.calcFrame();
            }
            return;
        }// end function

        public function addAnimation(param1:String, param2:Array, param3:Number = 0, param4:Boolean = true) : void
        {
            this._animations.push(new FlxAnim(param1, param2, param3, param4));
            return;
        }// end function

        public function addAnimationCallback(param1:Function) : void
        {
            this._callback = param1;
            return;
        }// end function

        public function play(param1:String, param2:Boolean = false) : void
        {
            if (!param2 && this._curAnim != null && param1 == this._curAnim.name && (this._curAnim.looped || !this.finished))
            {
                return;
            }
            this._curFrame = 0;
            this._curIndex = 0;
            this._frameTimer = 0;
            var _loc_3:uint = 0;
            var _loc_4:* = this._animations.length;
            while (_loc_3 < _loc_4)
            {
                
                if (this._animations[_loc_3].name == param1)
                {
                    this._curAnim = this._animations[_loc_3];
                    if (this._curAnim.delay <= 0)
                    {
                        this.finished = true;
                    }
                    else
                    {
                        this.finished = false;
                    }
                    this._curIndex = this._curAnim.frames[this._curFrame];
                    this.dirty = true;
                    return;
                }
                _loc_3 = _loc_3 + 1;
            }
            FlxG.log("WARNING: No animation called \"" + param1 + "\"");
            return;
        }// end function

        public function randomFrame() : void
        {
            this._curAnim = null;
            this._curIndex = int(FlxG.random() * (this._pixels.width / this.frameWidth));
            this.dirty = true;
            return;
        }// end function

        public function setOriginToCorner() : void
        {
            var _loc_1:int = 0;
            this.origin.y = 0;
            this.origin.x = _loc_1;
            return;
        }// end function

        public function centerOffsets(param1:Boolean = false) : void
        {
            this.offset.x = (this.frameWidth - width) * 0.5;
            this.offset.y = (this.frameHeight - height) * 0.5;
            if (param1)
            {
                x = x + this.offset.x;
                y = y + this.offset.y;
            }
            return;
        }// end function

        public function replaceColor(param1:uint, param2:uint, param3:Boolean = false) : Array
        {
            var _loc_6:uint = 0;
            var _loc_4:Array = null;
            if (param3)
            {
                _loc_4 = new Array();
            }
            var _loc_5:uint = 0;
            var _loc_7:* = this._pixels.height;
            var _loc_8:* = this._pixels.width;
            while (_loc_5 < _loc_7)
            {
                
                _loc_6 = 0;
                while (_loc_6 < _loc_8)
                {
                    
                    if (this._pixels.getPixel32(_loc_6, _loc_5) == param1)
                    {
                        this._pixels.setPixel32(_loc_6, _loc_5, param2);
                        if (param3)
                        {
                            _loc_4.push(new FlxPoint(_loc_6, _loc_5));
                        }
                        this.dirty = true;
                    }
                    _loc_6 = _loc_6 + 1;
                }
                _loc_5 = _loc_5 + 1;
            }
            return _loc_4;
        }// end function

        public function get pixels() : BitmapData
        {
            return this._pixels;
        }// end function

        public function set pixels(param1:BitmapData) : void
        {
            this._pixels = param1;
            var _loc_2:* = this._pixels.width;
            this.frameWidth = this._pixels.width;
            width = _loc_2;
            var _loc_2:* = this._pixels.height;
            this.frameHeight = this._pixels.height;
            height = _loc_2;
            this.resetHelpers();
            return;
        }// end function

        public function get facing() : uint
        {
            return this._facing;
        }// end function

        public function set facing(param1:uint) : void
        {
            if (this._facing != param1)
            {
                this.dirty = true;
            }
            this._facing = param1;
            return;
        }// end function

        public function get alpha() : Number
        {
            return this._alpha;
        }// end function

        public function set alpha(param1:Number) : void
        {
            if (param1 > 1)
            {
                param1 = 1;
            }
            if (param1 < 0)
            {
                param1 = 0;
            }
            if (param1 == this._alpha)
            {
                return;
            }
            this._alpha = param1;
            if (this._alpha != 1 || this._color != 16777215)
            {
                this._colorTransform = new ColorTransform((this._color >> 16) * 0.00392, (this._color >> 8 & 255) * 0.00392, (this._color & 255) * 0.00392, this._alpha);
            }
            else
            {
                this._colorTransform = null;
            }
            this.dirty = true;
            return;
        }// end function

        public function get color() : uint
        {
            return this._color;
        }// end function

        public function set color(param1:uint) : void
        {
            param1 = param1 & 16777215;
            if (this._color == param1)
            {
                return;
            }
            this._color = param1;
            if (this._alpha != 1 || this._color != 16777215)
            {
                this._colorTransform = new ColorTransform((this._color >> 16) * 0.00392, (this._color >> 8 & 255) * 0.00392, (this._color & 255) * 0.00392, this._alpha);
            }
            else
            {
                this._colorTransform = null;
            }
            this.dirty = true;
            return;
        }// end function

        public function get frame() : uint
        {
            return this._curIndex;
        }// end function

        public function set frame(param1:uint) : void
        {
            this._curAnim = null;
            this._curIndex = param1;
            this.dirty = true;
            return;
        }// end function

        override public function onScreen(param1:FlxCamera = null) : Boolean
        {
            if (param1 == null)
            {
                param1 = FlxG.camera;
            }
            getScreenXY(_point, param1);
            _point.x = _point.x - this.offset.x;
            _point.y = _point.y - this.offset.y;
            if ((angle == 0 || this._bakedRotation > 0) && this.scale.x == 1 && this.scale.y == 1)
            {
                return _point.x + this.frameWidth > 0 && _point.x < param1.width && _point.y + this.frameHeight > 0 && _point.y < param1.height;
            }
            var _loc_2:* = this.frameWidth / 2;
            var _loc_3:* = this.frameHeight / 2;
            var _loc_4:* = this.scale.x > 0 ? (this.scale.x) : (-this.scale.x);
            var _loc_5:* = this.scale.y > 0 ? (this.scale.y) : (-this.scale.y);
            var _loc_6:* = Math.sqrt(_loc_2 * _loc_2 + _loc_3 * _loc_3) * (_loc_4 >= _loc_5 ? (_loc_4) : (_loc_5));
            _point.x = _point.x + _loc_2;
            _point.y = _point.y + _loc_3;
            return _point.x + _loc_6 > 0 && _point.x - _loc_6 < param1.width && _point.y + _loc_6 > 0 && _point.y - _loc_6 < param1.height;
        }// end function

        public function pixelsOverlapPoint(param1:FlxPoint, param2:uint = 255, param3:FlxCamera = null) : Boolean
        {
            if (param3 == null)
            {
                param3 = FlxG.camera;
            }
            getScreenXY(_point, param3);
            _point.x = _point.x - this.offset.x;
            _point.y = _point.y - this.offset.y;
            this._flashPoint.x = param1.x - param3.scroll.x - _point.x;
            this._flashPoint.y = param1.y - param3.scroll.y - _point.y;
            return this.framePixels.hitTest(this._flashPointZero, param2, this._flashPoint);
        }// end function

        protected function calcFrame() : void
        {
            var _loc_1:* = this._curIndex * this.frameWidth;
            var _loc_2:uint = 0;
            var _loc_3:* = this._flipped ? (this._flipped) : (this._pixels.width);
            if (_loc_1 >= _loc_3)
            {
                _loc_2 = uint(_loc_1 / _loc_3) * this.frameHeight;
                _loc_1 = _loc_1 % _loc_3;
            }
            if (this._flipped && this._facing == LEFT)
            {
                _loc_1 = (this._flipped << 1) - _loc_1 - this.frameWidth;
            }
            this._flashRect.x = _loc_1;
            this._flashRect.y = _loc_2;
            this.framePixels.copyPixels(this._pixels, this._flashRect, this._flashPointZero);
            var _loc_4:int = 0;
            this._flashRect.y = 0;
            this._flashRect.x = _loc_4;
            if (this._colorTransform != null)
            {
                this.framePixels.colorTransform(this._flashRect, this._colorTransform);
            }
            if (this._callback != null)
            {
                this._callback(this._curAnim != null ? (this._curAnim.name) : (null), this._curFrame, this._curIndex);
            }
            this.dirty = false;
            return;
        }// end function

    }
}
